package hu.debrecen.adastra.card.config;

import hu.debrecen.adastra.card.repository.AccountRepository;
import hu.debrecen.adastra.card.repository.AchievementRepository;
import hu.debrecen.adastra.card.repository.BotAccountRepository;
import hu.debrecen.adastra.card.repository.PlayerStatisticsRepository;
import hu.debrecen.adastra.card.repository.UserConnectionRepository;
import hu.debrecen.adastra.card.repository.domain.BotAccount;
import hu.debrecen.adastra.card.service.BotService;
import hu.debrecen.adastra.card.service.CardGameFactory;
import hu.debrecen.adastra.card.service.GameStoreService;
import hu.debrecen.adastra.card.service.HeartbeatService;
import hu.debrecen.adastra.card.service.PlayerStatisticsService;
import hu.debrecen.adastra.card.service.SocialUserService;
import hu.debrecen.adastra.card.service.achievement.AchievementService;
import hu.debrecen.adastra.card.service.achievement.AvaiableAchievement;
import hu.debrecen.adastra.card.service.achievement.type.FirstCallAchievement;
import hu.debrecen.adastra.card.service.achievement.type.FirstCreateAchievement;
import hu.debrecen.adastra.card.service.achievement.type.FirstGameAchievement;
import hu.debrecen.adastra.card.service.achievement.type.FirstJoinAchievement;

import java.util.List;

import javax.inject.Inject;

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.collect.Lists;

@Configuration
public class ServiceConfig {

	@Inject
	private AccountRepository accountRepository;

	@Inject
	private AchievementRepository achievementRepository;

	@Inject
	private PlayerStatisticsRepository playerStatisticsRepository;

	@Inject
	private BotAccountRepository botAccountRepository;

	@Inject
	private UserConnectionRepository userConnectionRepository;

	@Inject
	private CacheManager cacheManager;

	@Bean
	public GameStoreService gameStoreService() {
		return new GameStoreService();
	}

	@Bean
	public PlayerStatisticsService playerStatisticsService() {
		return new PlayerStatisticsService(this.playerStatisticsRepository);
	}

	@Bean
	public SocialUserService socialUserService() {
		return new SocialUserService(this.accountRepository, this.userConnectionRepository);
	}

	@Bean
	public CardGameFactory cardGameFactory() {
		return new CardGameFactory(this.playerStatisticsService());
	}

	@Bean
	public AchievementService achievementService() {
		List<AvaiableAchievement> avaiableAchievements = Lists.newLinkedList();
		avaiableAchievements.add(new FirstJoinAchievement());
		avaiableAchievements.add(new FirstCreateAchievement());
		avaiableAchievements.add(new FirstGameAchievement());
		avaiableAchievements.add(new FirstCallAchievement());

		return new AchievementService(this.achievementRepository, this.playerStatisticsRepository, this.cacheManager, avaiableAchievements);
	}

	@Bean
	public HeartbeatService heartbeatService() {
		return new HeartbeatService(this.botService(), this.gameStoreService(), this.achievementService());
	}

	@Bean
	public BotService botService() {

		if (this.botAccountRepository.count() == 0) {
			this.botAccountRepository.save(new BotAccount("Hal-9000"));
			this.botAccountRepository.save(new BotAccount("Skynet"));

			for (int i = 0; i < 10; i++) {
				this.botAccountRepository.save(new BotAccount("Bot " + i));
			}

		}

		return new BotService(this.gameStoreService(), this.botAccountRepository, this.cardGameFactory());
	}

}
